package org.zfes.snowier.zbss.xzy.biz.solution.service.impl;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.zfes.snowier.core.data.DataSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.zfes.snowier.core.util.ZBeanUtil;
import org.zfes.snowier.core.util.ZObjectUtil;
import org.zfes.snowier.core.util.AppCtxUtil;
import org.zfes.snowier.core.util.ZAlert;
import org.zfes.snowier.core.util.ZAssert;
import org.zfes.snowier.core.data.ParamMap;
import com.google.common.collect.Lists;
import org.zfes.snowier.core.data.SelectVo;
import org.zfes.snowier.zbss.xzy.biz.solution.dao.SolutionAlgorithmMapper;
import org.zfes.snowier.zbss.xzy.biz.solution.model.Algorithm;
import org.zfes.snowier.zbss.xzy.biz.solution.model.SolutionAlgorithm;
import org.zfes.snowier.zbss.xzy.biz.solution.service.IAlgorithmService;
import org.zfes.snowier.zbss.xzy.biz.solution.service.ISolutionAlgorithmService;
import org.zfes.snowier.zbss.xzy.biz.solution.service.ISolutionService;

import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class SolutionAlgorithmServiceImpl implements ISolutionAlgorithmService{
 	@Autowired
	private SolutionAlgorithmMapper solutionAlgorithmMapper;
	
 	private ISolutionService solutionService;
 	private IAlgorithmService algorithmService;
 	
 	@Transactional(rollbackFor=Exception.class,readOnly = true)
 	@Override
 	public Map<Long,Integer> loadSolAlgCount(){
 		return solutionAlgorithmMapper.selectSolAlgCount();
 	}
 	
	@Transactional(rollbackFor=Exception.class,readOnly = true)
 	@Override
	public List<Algorithm> loadAlgorithmsSolutionBinded(Long solutionId){
 		if(solutionId==null) {
 			return Lists.newArrayList();
 		}
 		List<SolutionAlgorithm> saList = loadBySolutionId(solutionId,Byte.valueOf("1"));
 		if(ZObjectUtil.isEmpty(saList)) {
 			return Lists.newArrayList();
 		}
 		return  getAlgorithmService().loadByIds(saList.stream().map(v->v.getAlgorithmId()).collect(Collectors.toList()));
 		
 		
 	}
 	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void bindAlgorithm(Long solutionId , List<Long> algorithmIds) {
 		 ZAssert.notNull(solutionId, "请选择解决方案");
 		 ZAssert.notEmpty(algorithmIds, "请选择算法集");
 		 
 		List<SolutionAlgorithm>  dataIndb = solutionAlgorithmMapper.selectBySolutionId(solutionId,null);
 		
 		 algorithmIds.forEach(aid->{
 			 
 			Optional<SolutionAlgorithm>  asOp = dataIndb.stream().filter(v->aid.equals(v.getAlgorithmId())).findAny();//
 			if(asOp.isPresent()) {
 				if(Byte.valueOf("0").equals(asOp.get().getStatus())) {
 					solutionAlgorithmMapper.updateStatus(asOp.get().getId(), Byte.valueOf("1"));
 				}
 			}else {
 				createSolutionAlgorithm(new SolutionAlgorithm(solutionId, aid));
 			}
 		});
 	 }
 	
 	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void unBindAlgorithm(Long solutionId , List<Long> algorithmIds) {
 		 ZAssert.notNull(solutionId, "请选择解决方案");
 		 ZAssert.notEmpty(algorithmIds, "请选择算法集");
 		solutionAlgorithmMapper.updateStatusBatch(solutionId, algorithmIds,Byte.valueOf("0"));
 	}
 	
 	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void setSolutionAlgorithms(Long solutionId , List<Long> algorithmIds) {
 		 ZAssert.notNull(solutionId, "请选择解决方案");
 		 ZAssert.notEmpty(algorithmIds, "请选择算法集");
 		 
 		 //先全部解绑
 		solutionAlgorithmMapper.updateStatusBySolutionId(solutionId,Byte.valueOf("0"));
 		
 		//然后在绑定，全部
 		bindAlgorithm(solutionId,algorithmIds);
 		
 	}
	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void createSolutionAlgorithm(SolutionAlgorithm solutionAlgorithm) {
		ZBeanUtil.setCreateInfo(solutionAlgorithm);
		ZBeanUtil.validateBean(solutionAlgorithm);
		solutionAlgorithmMapper.insertSelective(solutionAlgorithm);
	}
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<SolutionAlgorithm> loadSolutionAlgorithmById(Long id) {
		if(id!=null){
			return Optional.ofNullable(solutionAlgorithmMapper.selectByPrimaryKey(id));
		}
		return Optional.empty();
		
	}

	
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void deleteSolutionAlgorithm(Long id) {
		ZAssert.notNull(id, "请选择要操作的数据");
		solutionAlgorithmMapper.deleteByPrimaryKey(id);
	}
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void setSolutionAlgorithmStatus(Long id, Byte status) {
		ZAssert.notNull(id, "请选择要操作的数据");
		ZAssert.notNull(status, "状态参数错误");
		if(!Stream.of(new Byte[] {-1,0,1}).anyMatch(val->val.equals(status))) {
			ZAlert.serviceLogicalError("状态参数错误");
		}
		solutionAlgorithmMapper.updateStatus( id,  status) ;
	}
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public DataSet loadSolutionAlgorithmDataSet(Map<String, Object> params) {
		ParamMap pm=ParamMap.filterParam(params);
		DataSet ds=DataSet.newDS2(solutionAlgorithmMapper.selectListCount(pm), solutionAlgorithmMapper.selectMapListPage(pm));
		return ds;
	}
	
	
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<SelectVo> loadSolutionAlgorithmSelectVo(Long solutionId) {
		
		List<Algorithm> algorithmList = getAlgorithmService().loadAllAlgorithm(Byte.valueOf("1"));
		
		 List<SolutionAlgorithm> salgList = loadBySolutionId(solutionId, Byte.valueOf("1"));
		
		 Set<Long> selectedAlgIds = salgList.stream().map(sa->sa.getAlgorithmId()).collect(Collectors.toSet());
		 
		 List<SelectVo> voList = algorithmList.stream().map(alg->{
				SelectVo selectVo= new SelectVo( alg.getId(),alg.getName()).putData("algCode", alg.getCode());
				if(selectedAlgIds.contains(alg.getId())) {
					selectVo.setSelected(true);
				}
				return selectVo;
			}).collect(Collectors.toList());
		 
		return voList==null?Lists.newArrayList():voList;
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<Long> loadCountSolutionId(Long solutionId,Byte status) {
		 if(solutionId==null) {
			 return Optional.of(0L);
		 }
		 return Optional.ofNullable(solutionAlgorithmMapper.selectCountSolutionId(solutionId, status));
	 }

	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<SolutionAlgorithm> loadBySolutionId(Long solutionId,Byte status) {
		if(solutionId==null) {
			return Lists.newArrayList();
		}
		return solutionAlgorithmMapper.selectBySolutionId(solutionId, status);
	}
	
 	IAlgorithmService getAlgorithmService(){
 		if(algorithmService==null) {
 			algorithmService=AppCtxUtil.cfg.getBean(IAlgorithmService.class);
 		}
 		return algorithmService;
 	}
 	
 	ISolutionService getSolutionService(){
 		if(solutionService==null) {
 			solutionService=AppCtxUtil.cfg.getBean(ISolutionService.class);
 		}
 		return solutionService;
 	}
}